#include "seg.h"
#include "cw32f030_rcc.h"
#include "cw32f030_gpio.h"
#include "cw32f030_btim.h"

static void Btim1_Configuration(void)
{
    BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct;
    __RCC_BTIM_CLK_ENABLE();

    /* NVIC Configuration */
    NVIC_EnableIRQ(BTIM1_IRQn); // 配置BTIM1中断

    BTIM_TimeBaseInitStruct.BTIM_Mode      = BTIM_Mode_TIMER;
    BTIM_TimeBaseInitStruct.BTIM_Period    = 1000 - 1;       // 1ms触发1次
    BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV64; // 1MHZ
    BTIM_TimeBaseInitStruct.BTIM_OPMode    = BTIM_OPMode_Repetitive;

    BTIM_TimeBaseInit(CW_BTIM1, &BTIM_TimeBaseInitStruct);
    BTIM_ITConfig(CW_BTIM1, BTIM_IT_OV, ENABLE);
    BTIM_Cmd(CW_BTIM1, ENABLE);
}

/*  共阴数码管编码表：
 0x3f   0x06   0x5b  0x4f  0x66  0x6d  0x7d  0x07  0x7f  0x6f
  0      1      2     3     4     5     6     7     8     9
 0xbf   0x86   0xdb  0xcf  0xe6  0xed  0xfd  0x87  0xff  0xef
  0.     1.     2.    3.    4.    5.    6.    7.    8.    9. */
static uint8_t Seg_Table[20] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
                                0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef};

void seg_init(void)
{
    __RCC_GPIOA_CLK_ENABLE(); // 打开GPIOA的时钟
    __RCC_GPIOB_CLK_ENABLE(); // 打开GPIOB的时钟

    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.Pins  = GPIO_PIN_2 | GPIO_PIN_0 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_15;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.IT    = GPIO_IT_NONE;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_Init(CW_GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pins  = GPIO_PIN_3 | GPIO_PIN_4;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.IT    = GPIO_IT_NONE;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
    Btim1_Configuration();
}

static uint8_t seg_codes[6];
void seg_decode(uint8_t segno, uint32_t num)
{
    if (segno > 1)
        return;

    uint8_t one, ten, hundred, thousand;
    thousand = num / 1000;
    num      = num % 1000;
    hundred  = num / 100;
    num      = num % 100;
    ten      = num / 10;
    num      = num % 10;
    one      = num;

    if (thousand) {
        seg_codes[0 + 3 * segno]     = Seg_Table[thousand];
        seg_codes[0 + 3 * segno + 1] = Seg_Table[hundred + 10];
        seg_codes[0 + 3 * segno + 2] = Seg_Table[ten];
    } else {
        seg_codes[0 + 3 * segno]     = Seg_Table[hundred + 10];
        seg_codes[0 + 3 * segno + 1] = Seg_Table[ten];
        seg_codes[0 + 3 * segno + 2] = Seg_Table[one];
    }
}

void seg_display(void)
{
    static uint8_t seg_index = 0;

    GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_SET);  // COM1:PA08
    GPIO_WritePin(CW_GPIOA, GPIO_PIN_11, GPIO_Pin_SET); // COM2:PA11
    GPIO_WritePin(CW_GPIOA, GPIO_PIN_12, GPIO_Pin_SET); // COM3:PA12
    GPIO_WritePin(CW_GPIOA, GPIO_PIN_15, GPIO_Pin_SET); // COM4:PA15
    GPIO_WritePin(CW_GPIOB, GPIO_PIN_3, GPIO_Pin_SET);  // COM5:PB03
    GPIO_WritePin(CW_GPIOB, GPIO_PIN_4, GPIO_Pin_SET);  // COM6:PB04

    uint8_t v = seg_codes[seg_index];
    for (uint8_t i = 0; i < 8; i++) {
        switch (i) {
            case 0:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_2, (GPIO_PinState)((v >> i) & 0x01)); // PA02,A
                break;
            case 1:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_0, (GPIO_PinState)((v >> i) & 0x01)); // PA00,B
                break;
            case 2:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_4, (GPIO_PinState)((v >> i) & 0x01)); // PA04,C
                break;
            case 3:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_6, (GPIO_PinState)((v >> i) & 0x01)); // PA06,D
                break;
            case 4:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_7, (GPIO_PinState)((v >> i) & 0x01)); // PA07,E
                break;
            case 5:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_1, (GPIO_PinState)((v >> i) & 0x01)); // PA01,F
                break;
            case 6:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_3, (GPIO_PinState)((v >> i) & 0x01)); // PA03,G
                break;
            case 7:
                GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, (GPIO_PinState)((v >> i) & 0x01)); // PA05,DP
                break;
            default:
                break;
        }
    }

    switch (seg_index) {
        case 0:
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_RESET); // PA08,COM1
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_11, GPIO_Pin_SET);  // PA11,COM2
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_12, GPIO_Pin_SET);  // PA12,COM3
            break;
        case 1:
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_SET);    // PA08,COM1
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_11, GPIO_Pin_RESET); // PA11,COM2
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_12, GPIO_Pin_SET);   // PA12,COM3
            break;
        case 2:
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_8, GPIO_Pin_SET);    // PA08,COM1
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_11, GPIO_Pin_SET);   // PA11,COM2
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_12, GPIO_Pin_RESET); // PA12,COM3
            break;
        case 3:
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_15, GPIO_Pin_RESET); // PA15,COM4
            GPIO_WritePin(CW_GPIOB, GPIO_PIN_3, GPIO_Pin_SET);    // PA3,COM5
            GPIO_WritePin(CW_GPIOB, GPIO_PIN_4, GPIO_Pin_SET);    // PA4,COM6
            break;
        case 4:
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_15, GPIO_Pin_SET);  // PA15,COM4
            GPIO_WritePin(CW_GPIOB, GPIO_PIN_3, GPIO_Pin_RESET); // PA3,COM5
            GPIO_WritePin(CW_GPIOB, GPIO_PIN_4, GPIO_Pin_SET);   // PA4,COM6
            break;
        case 5:
            GPIO_WritePin(CW_GPIOA, GPIO_PIN_15, GPIO_Pin_SET);  // PA15,COM4
            GPIO_WritePin(CW_GPIOB, GPIO_PIN_3, GPIO_Pin_SET);   // PA3,COM5
            GPIO_WritePin(CW_GPIOB, GPIO_PIN_4, GPIO_Pin_RESET); // PA4,COM6
            break;
        default:
            break;
    }

    seg_index = (seg_index + 1) % 6;
}
